package com.lost.octopus.es.helper.entity.wrapper;

import com.lost.octopus.es.helper.entity.model.FieldConfig;

import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 类似 in 查询,且每个in内都是一个年龄范围查询
 * 默认支持当-1时查询不为空，且复用年龄查询，包含
 * {@link EsQueryRangeAgeWrapper} 扩展
 * 可实现如： and ( (age>=1 and age<=5) or (age>=6 and age<=10) or (age is null))
 * 支持值为：["1,2","-1","0,8"]
 * <br/>
 * 注解：{@code @EsSearch(queryType = EsQueryMultiplyRangeAgeWrapper.class, fieldName = "birthday")}
 * <br/>
 * 示例：{@code new String[]{"0,1", "-1"}}
 * <br/>
 * 效果：{@code {"bool":{"should":[{"bool":{"must":[{"range":{"birthday":{"from":"20191218","to":"20211217","include_lower":true,"include_upper":true,"boost":1}}}]}},{"bool":{"must_not":[{"exists":{"field":"birthday","boost":1}}]}}]}} }
 * @author zhangbh
 **/
@Component
public class EsQueryMultiplyRangeAgeWrapper extends AbstractQueryWrapper {

    @Resource
    private EsQueryRangeAgeWrapper esQueryRangeAgeWrapper;
    @Resource
    private EsQueryBlankWrapper esQueryBlankWrapper;

    @Override
    public QueryBuilder addWrapper(BoolQueryBuilder builder, FieldConfig field) {
        Object defaultVal = field.getValue();
        if (!(defaultVal instanceof String[])) {
            throw new IllegalArgumentException("EsBoolQueryMultiplyRangeAgeWrapper 字段值类型必须是String[]!");
        }
        String[] value = (String[]) defaultVal;
        // 数组为空则不查询
        if (value.length == 0) {
            return null;
        }
        BoolQueryBuilder multiplyAgeQuery = QueryBuilders.boolQuery();
        for (String val : value) {
            // 这边可以随便先使用一个查询条件，只为了用返回值
            FieldConfig copy = field.copy();
            copy.setValue(val);
            QueryBuilder ageBuilder;
            // 如果是特殊的年龄查询（为空查询，则使用blankWrapper）
            if (EsQueryBlankWrapper.DEFAULT_OTHER_PARAM.equals(val)) {
                ageBuilder = esQueryBlankWrapper.addWrapper(QueryBuilders.boolQuery(), copy.copy(""));
            } else {
                ageBuilder = esQueryRangeAgeWrapper.addWrapper(QueryBuilders.boolQuery(), copy);
            }
            if (ageBuilder != null) {
                multiplyAgeQuery.should(ageBuilder);
            }
        }
        builder.must(multiplyAgeQuery);
        return multiplyAgeQuery;
    }
}
